"""System utilities"""

# pylint: disable=W0718:broad-exception-caught

from datetime import datetime, timedelta
from os import stat, walk, makedirs
from os.path import exists, isfile, getmtime, join, basename
import shutil


from loguru import logger


def copy_directory(src, dst):
    """Copy a directory from src to dst"""
    # Check if the source directory exists
    if not exists(src):
        logger.error(f"Source directory not exist: '{src}'")
        return

    # Delete the destination directory if it exists
    try:
        shutil.rmtree(dst)
        logger.success(f"Delete the directory successfully: '{dst}'")
    except PermissionError:
        logger.error(f"Permission error to delete the directory: '{dst}'")
    except FileNotFoundError:
        logger.info(f"Source directory not exist: '{dst}', no need to delete")

    # Copy the source directory to the destination
    try:
        shutil.copytree(src, dst)
        logger.success(f"Successfully copied directory '{src}' to '{dst}'")
    except FileExistsError:
        logger.error(f"Destination directory already exists: '{dst}'")
    except Exception as e:
        logger.error(f"Failed to copy directory from {src} to {dst}: {e}")


def make_dir_if_not_exists(path: str) -> bool:
    """Create a new directory at path if it doesn't exist already"""

    if not exists(path):
        makedirs(path)
        return True
    return False


def get_file_modification_time(file_path):
    """Get the modification time of a file"""

    if not isfile(file_path):
        logger.error(f"File does not exist: {file_path}")
        return None

    mod_time_timestamp = getmtime(file_path)
    mod_time = datetime.fromtimestamp(mod_time_timestamp)
    return mod_time


def find_file_in_directory(directory, filename):
    """Find a file with the given name within the specified directory"""

    for root, _, files in walk(directory):
        if filename in files:
            # If found, return its full path
            return join(root, filename)
    # If not found, return None
    return None


def get_filename_and_dir(path) -> tuple:
    """Get the filename and directory from a path"""

    return basename(path), path[: -len(basename(path))]


def file_updated_recently(file_path: str, duration: int = 3):
    """Check whether the file has been updated recently"""

    if not exists(file_path):
        logger.error(f"Index html file does not exist: {file_path}")
        return False

    mod_time = get_file_modification_time(file_path=file_path)
    file_size_kb = stat(file_path).st_size / 1024

    current_time = datetime.now()
    if current_time - mod_time > timedelta(seconds=duration):
        logger.error(
            f"File {file_path} has not been updated recently within {duration} seconds"
        )
        return False

    logger.info(
        f"Updated: {file_path}, last modify: {mod_time}, size: {file_size_kb} KB"
    )
    return True
